﻿module poo

open System

// Takes a 2D Binary Array with 1's representing tiles and 0's representing blank spaces and return an array of tuples of the coordinates of every vertex of the polygon made by the tiles
let VertexFind (x : int [,])=
    let mutable vertex = [||]
    for i in 0 .. (x.Length)-1 do
        //Checks for any vertices in the bottom row
        if(i < x.GetLength 0 - 1) then
            if(not(x.[i,0]=x.[i+1,0])) then
                vertex <- Array.append vertex [|(i+1,0)|]
        //Checks for any vertices in the left column
        if(i%x.GetLength 0 = 0 && i<x.Length - x.GetLength 0 - 1) then
            if(not(x.[0,i/(x.GetLength 0)]=x.[0,i/(x.GetLength 0)+1])) then
                vertex <- Array.append vertex [|(0,i/(x.GetLength 0)+1)|]
        //Checks for any vertices in the right column           
        if(i%x.GetLength 0 = x.GetLength 0 - 1  && i<x.Length - x.GetLength 0 - 1) then
            if(not(x.[x.GetLength 0 - 1,i/(x.GetLength 0)]=x.[x.GetLength 0 - 1,i/(x.GetLength 0)+1])) then
                vertex <- Array.append vertex [|(x.GetLength 0 ,i/(x.GetLength 0)+1)|]
        //Checks for any vertices in the top row 
        if(i > x.Length-x.GetLength 0 - 1 && i<x.Length-2) then
            if(not(x.[i%x.GetLength 0,x.Length/x.GetLength 0 - 1]=x.[i%x.GetLength 0+1,x.Length/x.GetLength 0 - 1])) then
                vertex <- Array.append vertex [|(i%x.GetLength 0+1,x.Length/x.GetLength 0 )|]
        //Checks for any vertices in everywhere that is not an edge
        if(not(i%(x.GetLength 0) = (x.GetLength 0 - 1)) && i<x.Length - x.GetLength 0 - 1) then
            let temp1 = x.[i%(x.GetLength 0),i/(x.GetLength 0)]
            let temp2 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)]
            let temp3 = x.[i%(x.GetLength 0),i/(x.GetLength 0)+1]
            let temp4 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)+1]
            if(temp1 = temp2 && temp2=temp3 && not(temp3 = temp4) ||temp1 = temp2 && temp2=temp4 && not(temp4 = temp3) || temp1 = temp4 && temp4=temp3 && not(temp3 = temp2) || temp4 = temp2 && temp2=temp3 && not(temp3 = temp1)) then
                vertex <- Array.append vertex [|(i%(x.GetLength 0)+1,i/(x.GetLength 0)+1)|]
        //Checks for vertex on the bottom left corner
        if(i =0 && x.[0,0] =1) then
            vertex <- Array.append vertex [|0,0|]
        //Checks for vertex on the bottom right corner
        if(i= x.GetLength 0 - 1 && x.[x.GetLength 0 - 1,0] =1) then
            vertex <- Array.append vertex [|x.GetLength 0 ,0|]
        //Checks for vertex on the top left corner
        if(i = x.Length-x.GetLength 0 - 1 && x.[0,x.Length/x.GetLength 0 - 1] =1) then
            vertex <- Array.append vertex [|0,x.Length/x.GetLength 0 |]
        //Checks for vertex on the top right corner
        if(i = x.Length - 1 && x.[x.GetLength 0 - 1,x.Length/x.GetLength 0 - 1] =1) then
            vertex <- Array.append vertex [|x.GetLength 0 ,x.Length/x.GetLength 0 |]
    vertex

// Takes a 2D Binary Array with 1's representing tiles and 0's representing blank spaces and return an array of tuples of the coordinates of every concave vertex of the polygon made by the tiles
let ConcaveVertexFind (x : int [,])=
    let mutable vertex = [||]
    for i in 0 .. x.Length - x.GetLength 0 - 1 do
          
        //Checks for any concave vertices in everywhere that is not an edge
        if(not(i%(x.GetLength 0) = (x.GetLength 0 - 1))) then
            let temp1 = x.[i%(x.GetLength 0),i/(x.GetLength 0)]
            let temp2 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)]
            let temp3 = x.[i%(x.GetLength 0),i/(x.GetLength 0)+1]
            let temp4 = x.[i%(x.GetLength 0)+1,i/(x.GetLength 0)+1]
            if(temp1 = temp2 && temp2=temp3 && not(temp3 = temp4) && temp4=0||temp1 = temp2 && temp2=temp4 && not(temp4 = temp3) && temp3=0|| temp1 = temp4 && temp4=temp3 && not(temp3 = temp2) && temp2=0|| temp4 = temp2 && temp2=temp3 && not(temp3 = temp1) && temp1=0) then
                vertex <- Array.append vertex [|(i%(x.GetLength 0)+1,i/(x.GetLength 0)+1)|]
            
    vertex 

let ConcaveFilter (x : int [,])  (a : (int*int)[]) =
    let b = ConcaveVertexFind x
    let b1 = Array.fold (fun (a : string) b -> a + b.ToString()) "" b
    let mutable c = [||]
    for i in 0 .. a.Length-1 do
        if b1.Contains (a.[i].ToString()) then
            c <- Array.append  c [|a.[i]|]
    c